/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sudoku;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import types.ISudokuMatrix;
import types.MatrixApplicableRules;
import types.SudokuMatrix;
import utils.SudokuMatrixIO;
import utils.SudokuSolver;
import rules.*;


/**
 * die hauptklasse unseres programmes.
 * how to use:
 * 1. invoke the constructur with the path of a sudoku file
 * 2. getMatrixApplicableRules liefrt die für aktuelle konfig. anwendbare rules
 * 3. setConf überführt die klasse in nächsten konfig
 * 4. getMatrixApplicableRules liefrt die für die neue konfig. anwendbare rules
 * usw.
 *
 * @author ali
 */
public class RuleBasedSudokuSolver {

   
    ISudokuMatrix currentconf;
    
    //beinhaltet eine komplett gelöste Sudoku
    ISudokuMatrix solvedMatrix;

    //MatrixApplicableRules verkörpert für jeden Feld ale anwendbare Rules der aktuellen Konfiguration
    MatrixApplicableRules mar = null;

    public RuleBasedSudokuSolver(ISudokuMatrix curConf) throws FileNotFoundException {

        currentconf = curConf;
        solvedMatrix = SudokuSolver.solveSudoku(currentconf);

        //adding all rules to mar (MatrixApplicableRules)
        Collection allRules = new ArrayList();
        allRules.add(new ColumnOneFree() );
        allRules.add(new ColumnSeveralFree() );
        allRules.add(new ColumnTwoFree() );
        allRules.add(new QuadratOneFree() );
        allRules.add(new QuadratTwoFreeCol() );
        allRules.add(new QuadratTwoFreeRow() );
        allRules.add(new RowOneFree() );
        allRules.add(new RowSeveralFree() );
        allRules.add(new RowThreeFree() );
        allRules.add(new RowTwoFree() );
        allRules.add(new ScanOtherColAndRow() );
        allRules.add(new QuadratSeveralFree());
       // allRules.add(new RowInTwoQuadratCompleteOrClosedAndTwoFieldsClosed() );
       // allRules.add(new RowTwinCandidateElimination());
     

        mar = new MatrixApplicableRules(allRules);
        mar.refreshApplicableRules(currentconf);
    }

    public MatrixApplicableRules getWholeMatrixApplicableRules() {
        return mar;
    }

    public void setConf (ISudokuMatrix curConf)
    {
        this.currentconf = curConf;
        mar.refreshApplicableRules(currentconf);
    }

    //liefert die Lösung für einen bestimmten pfad zurück
    //die Lösung ist immer richtig, weil sie durch backtracking berechnet wurde!
    public int getSolutionForField(int x, int y)
    {
        return (Integer)this.solvedMatrix.getElementAt(x, y);
    }

    public Collection getMatrixApplicableRules(int x, int y)
    {
        return mar.getApplicableRules(x, y);
    }
}
